/*
 * DungeonEventResource.cpp
 *
 *  Created on: 2013. 9. 10.
 *      Author: mega@gamevil.com
 */

#include "../User.h"
#include "../engine.h"
#include "../NLogic/Space.h"
#include "../NUtil/Utils.h"
#include "../NResource/Static.h"
#include "DungeonEventResource.h"

namespace ProjectZ { namespace NResource {

DungeonEventResource::DungeonEventResource()
{
	pDungeonEventAD		= new DungeonEventData;
	pDungeonEventIOS	= new DungeonEventData;
}

DungeonEventResource::~DungeonEventResource()
{
	delete pDungeonEventAD;
	delete pDungeonEventIOS;
}

bool DungeonEventResource::LoadResource()
{
	if (false == pDungeonEventAD->LoadResource(MARKET_GOOGLE, SC_KAKAO_GOOGLE))
		return false;

	if (false == pDungeonEventIOS->LoadResource(MARKET_IOS, SC_KAKAO_IOS))
		return false;

	return true;
}

DungeonEventData::Flyweight * DungeonEventResource::GetFly(User * pUser, int dungeonID)
{
	NUtil::MarketType marketType = NUtil::GetMarketType(pUser->GetUserInfo().company, pUser->GetUserInfo().sale_code);

	switch (marketType)
	{
	case NUtil::MarketType::AD_KAKAO:
		return pDungeonEventAD->GetFly(dungeonID);

	case NUtil::MarketType::IOS_KAKAO:
		return pDungeonEventIOS->GetFly(dungeonID);

	default:
		return NULL;
	}

	return NULL;
}


DungeonEventData::~DungeonEventData()
{
	std::for_each(clsFlyTree.begin(), clsFlyTree.end(), ProjectZ::NUtil::del_second_ptr<DATATREE::value_type>);
}

void
DungeonEventData::Clear()
{
	std::for_each(clsFlyTree.begin(), clsFlyTree.end(), ProjectZ::NUtil::del_second_ptr<DATATREE::value_type>);
	clsFlyTree.clear();
}

bool DungeonEventData::LoadResource(int company, int saleCode)
{
	::Database::Command::Auto clsAuto(::Database::GETCOMMANDPOOL());
	clsAuto->SetQueryType(::Database::Command::SELECT);
	clsAuto->MakeQuery("SELECT * FROM resource_dungeon_event WHERE company=%d AND sale_cd=%d", company, saleCode);

	if (false == ::Database::GETSESSION()->SyncExecute(1, clsAuto))
		return false;

	if( clsAuto->GetErrorIdx() != 0 )
		return false;

	if (0 == clsAuto->ResultRowCount())
		return false;

	Clear();

	while( clsAuto->Next() )
	{
		::Toolkit::Str<3> NATIONAL_CODE;
		int tmp_company;
		int tmp_salecode;
		Toolkit::Str<20> dungeonName;

		DungeonEventData::Flyweight * pFly = new DungeonEventData::Flyweight;

		clsAuto->GetRecord() >> NATIONAL_CODE >> tmp_company >> tmp_salecode >> pFly->_DUNGEON_ID >> dungeonName
				>> pFly->_EXP_1 >> pFly->_DROP_1 >> pFly->_GOLD_1
				>> pFly->_EXP_2 >> pFly->_DROP_2 >> pFly->_GOLD_2
				>> pFly->_EXP_3 >> pFly->_DROP_3 >> pFly->_GOLD_3
				>> pFly->_EXP_4 >> pFly->_DROP_4 >> pFly->_GOLD_4
				>> pFly->_EXP_5 >> pFly->_DROP_5 >> pFly->_GOLD_5
				>> pFly->_EXP_6 >> pFly->_DROP_6 >> pFly->_GOLD_6
				>> pFly->_EXP_7 >> pFly->_DROP_7 >> pFly->_GOLD_7;

		if (0 != Config::Instance().GetResourceDatabase()._strNational.compare(NATIONAL_CODE.c_str()))
		{
			DEBUGLOG("%s:%d NATIONAL_CODE ERROR!!! Config National Code [%s] , Resource National Code [%s]",
					__FILE__, __LINE__,
					Config::Instance().GetResourceDatabase()._strNational.c_str(),
					NATIONAL_CODE.c_str());
			return false;
		}

		clsFlyTree[pFly->_DUNGEON_ID] = pFly;
	}

	return true;
}

DungeonEventData::Flyweight * DungeonEventData::GetFly(int dungeonID)
{
	auto iter = clsFlyTree.find(dungeonID);

	if (iter == clsFlyTree.end())
		return NULL;

	return iter->second;
}


int
DungeonEventResource::GetWeightExp(User * pUser)
{
	/*
	 * 던전 요일별 경험치 가중치
	 */

	int weightExpRate = 100;	// 기본 비율

	// 이벤트 여부 확인
	if (false == NResource::Static::InstancePtr()->GetEventTime()->IsDungeonDayEvent(pUser))
	{
		return weightExpRate;
	}

	// 던전 요일별 이벤트 드랍률 데이터 조회
	NResource::CommonData::Key clsKey(3, 0);
	NResource::CommonData::Flyweight * pFlyCommon = NResource::Static::InstancePtr()->GetCommon()->GetFly(pUser, clsKey);
	if (NULL == pFlyCommon)
	{
		return weightExpRate;
	}

	// 이벤트 적용 대상 던전 여부 조회
	DungeonEventData::Flyweight * pFly = GetFly(pUser, pUser->GetSpace()->GetData()._table_id);
	if (NULL == pFly)
	{
		return weightExpRate;
	}

	time_t currentSec = time(NULL);
	struct tm *stTime = localtime(&currentSec);

	int isEvent = 0;

	switch (stTime->tm_wday)
	{
	case 0: isEvent = pFly->_EXP_7; break;
	case 1: isEvent = pFly->_EXP_1; break;
	case 2: isEvent = pFly->_EXP_2; break;
	case 3: isEvent = pFly->_EXP_3; break;
	case 4: isEvent = pFly->_EXP_4; break;
	case 5: isEvent = pFly->_EXP_5; break;
	case 6: isEvent = pFly->_EXP_6; break;
	}

	weightExpRate = pFlyCommon->_VALUE2;

	if (1 == isEvent)
	{
		weightExpRate = pFlyCommon->_VALUE1;
	}

	return weightExpRate;
}

int
DungeonEventResource::GetWeightDropRate(User * pUser)
{
	/*
	 * 던전 요일별 드랍률 가중치
	 */

	int weightDropRate = 100;	// 기본 비율

	// 이벤트 여부 확인
	if (false == NResource::Static::InstancePtr()->GetEventTime()->IsDungeonDayEvent(pUser))
	{
		return weightDropRate;
	}

	// 던전 요일별 이벤트 드랍률 데이터 조회
	NResource::CommonData::Key clsKey(3, 1);
	NResource::CommonData::Flyweight * pFlyCommon = NResource::Static::InstancePtr()->GetCommon()->GetFly(pUser, clsKey);
	if (NULL == pFlyCommon)
	{
		return weightDropRate;
	}

	// 이벤트 적용 대상 던전 여부 조회
	DungeonEventData::Flyweight * pFly = GetFly(pUser, pUser->GetSpace()->GetData()._table_id);
	if (NULL == pFly)
	{
		return weightDropRate;
	}

	time_t currentSec = time(NULL);
	struct tm *stTime = localtime(&currentSec);

	int isEvent = 0;

	switch (stTime->tm_wday)
	{
	case 0: isEvent = pFly->_DROP_7; break;
	case 1: isEvent = pFly->_DROP_1; break;
	case 2: isEvent = pFly->_DROP_2; break;
	case 3: isEvent = pFly->_DROP_3; break;
	case 4: isEvent = pFly->_DROP_4; break;
	case 5: isEvent = pFly->_DROP_5; break;
	case 6: isEvent = pFly->_DROP_6; break;
	}

	weightDropRate = pFlyCommon->_VALUE2;

	if (1 == isEvent)
	{
		weightDropRate = pFlyCommon->_VALUE1;
	}

	return weightDropRate;
}

int
DungeonEventResource::GetWeightGold(User * pUser)
{
	/*
	 * 던전 요일별 골드 가중치
	 */

	int weightGoldRate = 100;	// 기본 비율

	// 이벤트 여부 확인
	if (false == NResource::Static::InstancePtr()->GetEventTime()->IsDungeonDayEvent(pUser))
	{
		return weightGoldRate;
	}

	// 던전 요일별 이벤트 드랍률 데이터 조회
	NResource::CommonData::Key clsKey(3, 2);
	NResource::CommonData::Flyweight * pFlyCommon = NResource::Static::InstancePtr()->GetCommon()->GetFly(pUser, clsKey);
	if (NULL == pFlyCommon)
	{
		return weightGoldRate;
	}

	// 이벤트 적용 대상 던전 여부 조회
	DungeonEventData::Flyweight * pFly = GetFly(pUser, pUser->GetSpace()->GetData()._table_id);
	if (NULL == pFly)
	{
		return weightGoldRate;
	}

	time_t currentSec = time(NULL);
	struct tm *stTime = localtime(&currentSec);

	int isEvent = 0;

	switch (stTime->tm_wday)
	{
	case 0: isEvent = pFly->_GOLD_7; break;
	case 1: isEvent = pFly->_GOLD_1; break;
	case 2: isEvent = pFly->_GOLD_2; break;
	case 3: isEvent = pFly->_GOLD_3; break;
	case 4: isEvent = pFly->_GOLD_4; break;
	case 5: isEvent = pFly->_GOLD_5; break;
	case 6: isEvent = pFly->_GOLD_6; break;
	}

	weightGoldRate = pFlyCommon->_VALUE2;

	if (1 == isEvent)
	{
		weightGoldRate = pFlyCommon->_VALUE1;
	}

	return weightGoldRate;
}

} /*NResource*/ } /* namespace ProjectZ */
